package com.blog.cmrpersonalblog.controller;

import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.blog.cmrpersonalblog.common.Result;
import com.blog.cmrpersonalblog.dto.tag.requset.TagBatchOperationRequest;
import com.blog.cmrpersonalblog.dto.tag.requset.TagCreateRequest;
import com.blog.cmrpersonalblog.dto.tag.requset.TagQueryRequest;
import com.blog.cmrpersonalblog.dto.tag.requset.TagUpdateRequest;
import com.blog.cmrpersonalblog.dto.tag.respnose.TagManagementResponse;
import com.blog.cmrpersonalblog.entity.ArticleTag;
import com.blog.cmrpersonalblog.service.TagManagementService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.NotBlank;
import java.util.List;
import java.util.Map;

/**
 * 标签管理控制器
 * 提供标签的管理功能，包括列表查询、创建、更新、删除、批量操作等
 */
@Slf4j
@RestController
@RequestMapping("/admin/tags")
@CrossOrigin(origins = "*", maxAge = 3600)
@SaCheckRole("admin")
@Validated
public class TagManagementController {

   @Resource
    private TagManagementService tagManagementService;

    /**
     * 分页查询标签列表
     */
    @GetMapping("/list")
    public Result<IPage<TagManagementResponse>> getTagList(TagQueryRequest queryRequest) {
        log.info("管理员查询标签列表: {}", queryRequest);
        try {
            IPage<TagManagementResponse> pageResult = tagManagementService.getTagList(queryRequest);
            return Result.success(pageResult);
        } catch (Exception e) {
            log.error("查询标签列表失败", e);
            return Result.error("查询标签列表失败：" + e.getMessage());
        }
    }

    /**
     * 获取标签详情
     */
    @GetMapping("/{tagId}")
    public Result<TagManagementResponse> getTagDetail(@PathVariable @NotNull Long tagId) {
        log.info("管理员查看标签详情: tagId={}", tagId);
        try {
            TagManagementResponse tagDetail = tagManagementService.getTagDetail(tagId);
            if (tagDetail == null) {
                return Result.error("标签不存在");
            }
            return Result.success(tagDetail);
        } catch (Exception e) {
            log.error("获取标签详情失败", e);
            return Result.error("获取标签详情失败：" + e.getMessage());
        }
    }

    /**
     * 创建标签
     */
    @PostMapping("/create")
    public Result<Void> createTag(@RequestBody @Valid TagCreateRequest createRequest) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员创建标签: request={}, operatorId={}", createRequest, operatorId);
        
        try {
            boolean success = tagManagementService.createTag(createRequest, operatorId);
            if (success) {
                return Result.success("标签创建成功");
            } else {
                return Result.error("标签创建失败");
            }
        } catch (Exception e) {
            log.error("创建标签失败", e);
            return Result.error("创建标签失败：" + e.getMessage());
        }
    }

    /**
     * 更新标签
     */
    @PutMapping("/update")
    public Result<Void> updateTag(@RequestBody @Valid TagUpdateRequest updateRequest) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员更新标签: request={}, operatorId={}", updateRequest, operatorId);
        
        try {
            boolean success = tagManagementService.updateTag(updateRequest, operatorId);
            if (success) {
                return Result.success("标签更新成功");
            } else {
                return Result.error("标签更新失败");
            }
        } catch (Exception e) {
            log.error("更新标签失败", e);
            return Result.error("更新标签失败：" + e.getMessage());
        }
    }

    /**
     * 删除标签
     */
    @DeleteMapping("/{tagId}")
    public Result<Void> deleteTag(@PathVariable @NotNull Long tagId) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员删除标签: tagId={}, operatorId={}", tagId, operatorId);
        
        try {
            boolean success = tagManagementService.deleteTag(tagId, operatorId);
            if (success) {
                return Result.success("标签删除成功");
            } else {
                return Result.error("标签删除失败");
            }
        } catch (Exception e) {
            log.error("删除标签失败", e);
            return Result.error("删除标签失败：" + e.getMessage());
        }
    }

    /**
     * 批量操作标签
     */
    @PostMapping("/batch")
    public Result<Map<String, Object>> batchOperateTags(@RequestBody @Valid TagBatchOperationRequest batchRequest) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员批量操作标签: request={}, operatorId={}", batchRequest, operatorId);
        
        try {
            Map<String, Object> result = tagManagementService.batchOperateTags(batchRequest, operatorId);
            if ((Boolean) result.get("success")) {
                return Result.success("批量操作成功", result);
            } else {
                return Result.error("批量操作失败：" + result.get("error"));
            }
        } catch (Exception e) {
            log.error("批量操作标签失败", e);
            return Result.error("批量操作失败：" + e.getMessage());
        }
    }

    /**
     * 启用标签
     */
    @PostMapping("/{tagId}/enable")
    public Result<Void> enableTag(@PathVariable @NotNull Long tagId) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员启用标签: tagId={}, operatorId={}", tagId, operatorId);
        
        try {
            boolean success = tagManagementService.enableTag(tagId, operatorId);
            if (success) {
                return Result.success("标签启用成功");
            } else {
                return Result.error("标签启用失败");
            }
        } catch (Exception e) {
            log.error("启用标签失败", e);
            return Result.error("启用标签失败：" + e.getMessage());
        }
    }

    /**
     * 禁用标签
     */
    @PostMapping("/{tagId}/disable")
    public Result<Void> disableTag(@PathVariable @NotNull Long tagId) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员禁用标签: tagId={}, operatorId={}", tagId, operatorId);
        
        try {
            boolean success = tagManagementService.disableTag(tagId, operatorId);
            if (success) {
                return Result.success("标签禁用成功");
            } else {
                return Result.error("标签禁用失败");
            }
        } catch (Exception e) {
            log.error("禁用标签失败", e);
            return Result.error("禁用标签失败：" + e.getMessage());
        }
    }

    /**
     * 更新标签颜色
     */
    @PostMapping("/{tagId}/color")
    public Result<Void> updateTagColor(@PathVariable @NotNull Long tagId, 
                                      @RequestParam @NotBlank String color) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员更新标签颜色: tagId={}, color={}, operatorId={}", tagId, color, operatorId);
        
        try {
            boolean success = tagManagementService.updateTagColor(tagId, color, operatorId);
            if (success) {
                return Result.success("标签颜色更新成功");
            } else {
                return Result.error("标签颜色更新失败");
            }
        } catch (Exception e) {
            log.error("更新标签颜色失败", e);
            return Result.error("更新标签颜色失败：" + e.getMessage());
        }
    }

    /**
     * 重置标签使用次数
     */
    @PostMapping("/{tagId}/reset-count")
    public Result<Void> resetTagUseCount(@PathVariable @NotNull Long tagId) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员重置标签使用次数: tagId={}, operatorId={}", tagId, operatorId);
        
        try {
            boolean success = tagManagementService.resetTagUseCount(tagId, operatorId);
            if (success) {
                return Result.success("标签使用次数重置成功");
            } else {
                return Result.error("标签使用次数重置失败");
            }
        } catch (Exception e) {
            log.error("重置标签使用次数失败", e);
            return Result.error("重置标签使用次数失败：" + e.getMessage());
        }
    }

    /**
     * 获取启用的标签列表（用于下拉选择）
     */
    @GetMapping("/enabled")
    public Result<List<ArticleTag>> getEnabledTags() {
        log.info("获取启用的标签列表");
        try {
            List<ArticleTag> tags = tagManagementService.getEnabledTags();
            return Result.success(tags);
        } catch (Exception e) {
            log.error("获取启用标签列表失败", e);
            return Result.error("获取标签列表失败：" + e.getMessage());
        }
    }

    /**
     * 获取热门标签列表
     */
    @GetMapping("/popular")
    public Result<List<ArticleTag>> getPopularTags(@RequestParam(defaultValue = "10") Integer limit) {
        log.info("获取热门标签列表: limit={}", limit);
        try {
            List<ArticleTag> tags = tagManagementService.getPopularTags(limit);
            return Result.success(tags);
        } catch (Exception e) {
            log.error("获取热门标签列表失败", e);
            return Result.error("获取热门标签列表失败：" + e.getMessage());
        }
    }

    /**
     * 获取最近创建的标签
     */
    @GetMapping("/recent")
    public Result<List<ArticleTag>> getRecentTags(@RequestParam(defaultValue = "10") Integer limit) {
        log.info("获取最近创建的标签: limit={}", limit);
        try {
            List<ArticleTag> tags = tagManagementService.getRecentTags(limit);
            return Result.success(tags);
        } catch (Exception e) {
            log.error("获取最近创建标签失败", e);
            return Result.error("获取最近创建标签失败：" + e.getMessage());
        }
    }

    /**
     * 检查标签名称是否可用
     */
    @GetMapping("/check-name")
    public Result<Boolean> checkTagName(@RequestParam String name, 
                                       @RequestParam(required = false) Long excludeId) {
        log.info("检查标签名称是否存在: name={}, excludeId={}", name, excludeId);
        try {
            boolean exists = tagManagementService.existsTagName(name, excludeId);
            return Result.success(!exists); // 返回是否可用（不存在则可用）
        } catch (Exception e) {
            log.error("检查标签名称失败", e);
            return Result.error("检查标签名称失败：" + e.getMessage());
        }
    }

    /**
     * 搜索标签（用于自动完成）
     */
    @GetMapping("/search")
    public Result<List<ArticleTag>> searchTags(@RequestParam String keyword, 
                                              @RequestParam(defaultValue = "10") Integer limit) {
        log.info("搜索标签: keyword={}, limit={}", keyword, limit);
        try {
            List<ArticleTag> tags = tagManagementService.searchTags(keyword, limit);
            return Result.success(tags);
        } catch (Exception e) {
            log.error("搜索标签失败", e);
            return Result.error("搜索标签失败：" + e.getMessage());
        }
    }

    /**
     * 获取相似标签
     */
    @GetMapping("/similar")
    public Result<List<ArticleTag>> getSimilarTags(@RequestParam String tagName, 
                                                  @RequestParam(defaultValue = "5") Integer limit) {
        log.info("获取相似标签: tagName={}, limit={}", tagName, limit);
        try {
            List<ArticleTag> tags = tagManagementService.getSimilarTags(tagName, limit);
            return Result.success(tags);
        } catch (Exception e) {
            log.error("获取相似标签失败", e);
            return Result.error("获取相似标签失败：" + e.getMessage());
        }
    }

    /**
     * 合并标签
     */
    @PostMapping("/merge")
    public Result<Void> mergeTags(@RequestParam List<Long> sourceTagIds, 
                                 @RequestParam Long targetTagId) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员合并标签: sourceTagIds={}, targetTagId={}, operatorId={}", 
            sourceTagIds, targetTagId, operatorId);
        
        try {
            boolean success = tagManagementService.mergeTags(sourceTagIds, targetTagId, operatorId);
            if (success) {
                return Result.success("标签合并成功");
            } else {
                return Result.error("标签合并失败");
            }
        } catch (Exception e) {
            log.error("合并标签失败", e);
            return Result.error("合并标签失败：" + e.getMessage());
        }
    }

    /**
     * 获取未使用的标签列表
     */
    @GetMapping("/unused")
    public Result<List<ArticleTag>> getUnusedTags() {
        log.info("获取未使用的标签列表");
        try {
            List<ArticleTag> tags = tagManagementService.getUnusedTags();
            return Result.success(tags);
        } catch (Exception e) {
            log.error("获取未使用标签列表失败", e);
            return Result.error("获取未使用标签列表失败：" + e.getMessage());
        }
    }

    /**
     * 清理未使用的标签
     */
    @PostMapping("/cleanup")
    public Result<Integer> cleanupUnusedTags(@RequestParam(defaultValue = "30") Integer daysBefore) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员清理未使用标签: daysBefore={}, operatorId={}", daysBefore, operatorId);
        
        try {
            int cleanupCount = tagManagementService.cleanupUnusedTags(daysBefore, operatorId);
            return Result.success("清理完成，共清理 " + cleanupCount + " 个标签", cleanupCount);
        } catch (Exception e) {
            log.error("清理未使用标签失败", e);
            return Result.error("清理未使用标签失败：" + e.getMessage());
        }
    }

    /**
     * 同步标签使用次数
     */
    @PostMapping("/sync-counts")
    public Result<Map<String, Object>> syncTagUseCounts() {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员同步标签使用次数: operatorId={}", operatorId);
        
        try {
            Map<String, Object> result = tagManagementService.syncTagUseCounts(operatorId);
            if ((Boolean) result.get("success")) {
                return Result.success("同步成功", result);
            } else {
                return Result.error("同步失败：" + result.get("error"));
            }
        } catch (Exception e) {
            log.error("同步标签使用次数失败", e);
            return Result.error("同步失败：" + e.getMessage());
        }
    }

    /**
     * 获取标签统计信息
     */
    @GetMapping("/statistics")
    public Result<Map<String, Object>> getTagStatistics() {
        log.info("获取标签统计信息");
        try {
            Map<String, Object> statistics = tagManagementService.getTagStatistics();
            return Result.success(statistics);
        } catch (Exception e) {
            log.error("获取标签统计信息失败", e);
            return Result.error("获取统计信息失败：" + e.getMessage());
        }
    }

    /**
     * 获取标签状态分布
     */
    @GetMapping("/status-distribution")
    public Result<List<Map<String, Object>>> getTagStatusDistribution() {
        log.info("获取标签状态分布");
        try {
            List<Map<String, Object>> distribution = tagManagementService.getTagStatusDistribution();
            return Result.success(distribution);
        } catch (Exception e) {
            log.error("获取标签状态分布失败", e);
            return Result.error("获取状态分布失败：" + e.getMessage());
        }
    }

    /**
     * 获取标签使用频率分布
     */
    @GetMapping("/usage-distribution")
    public Result<List<Map<String, Object>>> getTagUsageDistribution() {
        log.info("获取标签使用频率分布");
        try {
            List<Map<String, Object>> distribution = tagManagementService.getTagUsageDistribution();
            return Result.success(distribution);
        } catch (Exception e) {
            log.error("获取标签使用频率分布失败", e);
            return Result.error("获取使用频率分布失败：" + e.getMessage());
        }
    }

    /**
     * 获取标签颜色分布统计
     */
    @GetMapping("/color-distribution")
    public Result<List<Map<String, Object>>> getTagColorDistribution() {
        log.info("获取标签颜色分布统计");
        try {
            List<Map<String, Object>> distribution = tagManagementService.getTagColorDistribution();
            return Result.success(distribution);
        } catch (Exception e) {
            log.error("获取标签颜色分布统计失败", e);
            return Result.error("获取颜色分布统计失败：" + e.getMessage());
        }
    }

    /**
     * 获取标签趋势统计
     */
    @GetMapping("/trend-statistics")
    public Result<List<Map<String, Object>>> getTagTrendStatistics(@RequestParam(defaultValue = "12") Integer months) {
        log.info("获取标签趋势统计: months={}", months);
        try {
            List<Map<String, Object>> statistics = tagManagementService.getTagTrendStatistics(months);
            return Result.success(statistics);
        } catch (Exception e) {
            log.error("获取标签趋势统计失败", e);
            return Result.error("获取趋势统计失败：" + e.getMessage());
        }
    }
}
